﻿using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using SST.WebClient.Data;
using System.Text;
using System.IO;
using SST.WebClient.Util;
using System.Text.RegularExpressions;

namespace SST.WebClient
{
    /// <summary>
    /// Provide website account related functions
    /// </summary>
    public class AccountService
    {
        public event EventHandler<AccountServiceLoginAsyncEventArgs> LoginAsyncCompleted;
        
        /// <summary>
        /// Login the website
        /// </summary>
        /// <param name="user"></param>
        /// <returns>True if success</returns>
        public void LoginAsync(UserAccount user)
        {
            //http://stackoverflow.com/questions/793755/how-to-fill-forms-and-submit-with-webclient-in-c-sharp
            var encoding = Encoding.GetEncoding("ISO-8859-1");
            var postData = "username=" + HttpUtility.UrlEncode(user.Username)
                + "&user_password=" + HttpUtility.UrlEncode(user.Password)
                + "&op=login";
            byte[] data = encoding.GetBytes(postData);

            Helper.PostToWeb(new Uri("http://www.streamingsoundtracks.com/modules.php?name=Your_Account")
                , data, true, null
                , (responseString, cookie) =>
                {
                    //parse
                    if (responseString.Contains("Login Incorrect"))
                    {
                        OnLoginAsyncCompleted(new AccountServiceLoginAsyncEventArgs(false));
                        return;
                    }

                    user.SessionCookie = cookie;
                    //then need to get chat password
                    GetChatPasswordAsync(user, new Action(() =>
                    {
                        if (user.UserPw != null)
                            OnLoginAsyncCompleted(new AccountServiceLoginAsyncEventArgs(true));
                        else
                            OnLoginAsyncCompleted(new AccountServiceLoginAsyncEventArgs(false));
                    }));
                }
            );
        }

        private void GetChatPasswordAsync(UserAccount user, Action callback)
        {
            Helper.PostToWeb(new Uri("http://www.streamingsoundtracks.com/modules.php?name=About_SST")
                , null, false, user.SessionCookie,
                (responseString, cookie) =>
                {
                    if (responseString == null)
                    {
                        callback();
                        return;
                    }

                    Regex pattern = new Regex(
                        "userpw="       //userpw start
                        + "("           //group 1 start
                        + "[^\"]+"      //match except double quote
                        + ")"           //group 1 end
                        + "\""          //close double quote
                        , RegexOptions.Compiled);
                    Match m = pattern.Match(responseString);
                    if (!m.Success)
                    {
                        Helper.Debug("get userpw failed");
                        callback();
                        return;
                    }

                    user.UserPw = m.Groups[1].Value;
                    callback();
                }
            );
        }

        // Wrap event invocations inside a protected virtual method
        // to allow derived classes to override the event invocation behavior
        protected virtual void OnLoginAsyncCompleted(AccountServiceLoginAsyncEventArgs e)
        {
            // Make a temporary copy of the event to avoid possibility of
            // a race condition if the last subscriber unsubscribes
            // immediately after the null check and before the event is raised.
            EventHandler<AccountServiceLoginAsyncEventArgs> handler = LoginAsyncCompleted;

            // Event will be null if there are no subscribers
            if (handler != null)
            {
                // Use the () operator to raise the event.
                System.Windows.Deployment.Current.Dispatcher.BeginInvoke(() => { handler(this, e); });
            }
        }
    }

    /// <summary>
    /// Contains chat message list
    /// </summary>
    public class AccountServiceLoginAsyncEventArgs : EventArgs
    {
        private bool _Success;

        public bool Success
        {
            get { return _Success; }
            set { _Success = value; }
        }

        public AccountServiceLoginAsyncEventArgs(bool success)
        {
            this._Success = success;
        }
    }
}
